import google_prediction
import random
import httplib2
import logging

from google.appengine.ext import db
from oauth2client.appengine import CredentialsProperty
from oauth2client.appengine import StorageByKeyName
from apiclient.discovery import build

  
class Credentials(db.Model):
    credentials = CredentialsProperty()

class PredictionModel(db.Model):
    name = db.StringProperty(required=True)
    owner = db.UserProperty()
    public = db.BooleanProperty(required=True, default=False)
    trained = db.BooleanProperty(required=True, default=False)
    categories = db.StringListProperty()
    acl = db.StringListProperty()

    category_tuples = property(lambda self: enumerate(self.categories))
    
    def predict(self, query):
        """Generates a prediction for one query."""
        config = ConfigModel.get_config()
        credentials = config.credentials
        if credentials:
            # call the prediction API
            http = httplib2.Http()
            http = credentials.authorize(http)
            service = build("prediction", "v1.2", http=http)
            #weird behavior of prediction api reflection, which requires both data and body params with same values
            result = service.predict(data='%s/model-%d' % (config.bucket_name, self.key().id()),
                                     body={"input":{"csvInstance":[ query['iso_language_code'], query['text']]}}).execute()
            index = result['outputLabel'].split('-')[1]
            logging.info(index)
            return self.categories[int(index)]

  #this thing is not documented and does not work with current api
  #def predict_many(self, queries):
  #  """Generates predictions for a set of queries."""
  #  auth = ConfigModel.get_by_key_name('config')
  #  return google_prediction.BatchPredict(
  #      auth.prediction_auth,
  #      "%s/model-%d" % (auth.bucket_name, self.key().id()),
  #      queries)


class TrainingRecord(db.Model):
    """Represents a single row of training data.

    Child entity of the PredictionModel it applies to.
    """
    owner = db.UserProperty(required=True)
    tid = db.IntegerProperty(required=True)
    language_code = db.StringProperty(required=True)
    text = db.TextProperty(required=True)
    href = db.StringProperty(required=True)
    category = db.StringProperty(required=True)
    pushed = db.BooleanProperty(default=False)

class ConfigModel(db.Model):
    """Represents the application configuration.

    Holds application id, secret and OAuth tokens
    """
    client_id = db.StringProperty()
    client_secret = db.StringProperty()
    storage_project_id = db.StringProperty()
    bucket_name = db.StringProperty()
    credentials = CredentialsProperty()
    
    @classmethod
    def get_config(cls):
        return cls.get_by_key_name("config")


